package cn.edu.njnu.opengmpback.user.controller;

import cn.edu.njnu.opengmpback.Modeling.entity.dto.ProjectPageDTO;
import cn.edu.njnu.opengmpback.common.dto.PageDTO;
import cn.edu.njnu.opengmpback.common.utils.CommonService;
import cn.edu.njnu.opengmpback.common.utils.JsonResult;
import cn.edu.njnu.opengmpback.common.utils.ResultUtils;
import cn.edu.njnu.opengmpback.user.dao.HistoryDao;
import cn.edu.njnu.opengmpback.user.entity.History;
import cn.edu.njnu.opengmpback.user.entity.UserEntity;
import cn.edu.njnu.opengmpback.user.entity.UserVo;
import cn.edu.njnu.opengmpback.user.service.HistoryService;
import cn.edu.njnu.opengmpback.user.service.UserService;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@RestController
@RequestMapping(value = "/user")
public class UserController {

    @Autowired
    UserService userService;

    @Autowired
    HistoryService historyService;

    @Autowired
    HistoryDao historyDao;

    @Autowired
    CommonService commonService;

    /**
     * Handles user registration by delegating to the UserService.
     *
     * @param user    the UserEntity to be registered
     * @return        JsonResult containing the result of the registration
     */
    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public JsonResult register(@RequestBody UserEntity user) {
        return userService.registerService(user);
    }

    /**
     * Handles user login by delegating to the UserService.
     *
     * @param  jsonObject  the JSONObject containing the user's email and password
     * @param  request     the HttpServletRequest object
     * @return             JsonResult containing the result of the login
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public JsonResult login(@RequestBody JSONObject jsonObject,
                            HttpServletRequest request) {
        String email = jsonObject.getString("email");
        String password = jsonObject.getString("password");
        String ipAddr = userService.getIpAddr(request);
        JsonResult loginResult = userService.loginAndAcquireInfo(email, password, ipAddr);
        if (loginResult.getCode() != 0) {
            return loginResult;
        }
        return loginResult;
    }

    @RequestMapping(value = "/refreshToken", method = RequestMethod.POST)
    public JsonResult login(@RequestBody String refreshToken) {
        return userService.refreshToken(refreshToken);
    }

    /**
     * Sends a reset password email to the user with the specified email address.
     *
     * @param email    the email address of the user to send the reset password email to
     * @return         a JsonResult containing the result of the email sending operation
     */
    @RequestMapping(value = "/sendEmail/{email}", method = RequestMethod.GET)
    public JsonResult sendCode(@PathVariable String email) {
        return userService.sendResetPwdEmail(email);
    }

    /**
     * Resets the user's password using a provided code.
     *
     * @return         the result of the password reset operation
     */
    @RequestMapping(value = "/changePwd", method = RequestMethod.POST)
    public JsonResult changePassword(@RequestBody JSONObject jsonObject) {
        String email = jsonObject.getString("email");
        String code = jsonObject.getString("code");
        String newPwd = jsonObject.getString("newPwd");
        return userService.resetPwdByCode(email, code, newPwd);
    }

    /**
     * Resets the user's password using a provided email, old password, and new password.
     *
     * @param  oldPwd   the user's current password
     * @param  newPwd   the new password to be set for the user
     * @return           a JsonResult containing the result of the password reset operation
     */
    @RequestMapping(value = "/resetPwd/{oldPwd}/{newPwd}", method = RequestMethod.GET)
    public JsonResult resetPassword(@PathVariable("oldPwd") String oldPwd,
                                    @PathVariable("newPwd") String newPwd,
                                    HttpServletRequest request) {
        return userService.resetPwdByOldPwd(oldPwd, newPwd, request);
    }

    /**
     * check the user state.
     *
     * @param  req     HttpServletRequest object
     * @return         the result of the user state operation
     */
    @RequestMapping(value = "/state", method = RequestMethod.POST)
    public Object userState(HttpServletRequest req) {
        return userService.userState(req);
    }

    /**
     * Handles the HTTP POST request to upload a user's avatar.
     *
     * @param req the HttpServletRequest object containing the request data
     * @return a JsonResult object containing the result of the avatar upload operation
     */
    @RequestMapping(value = "/avatar", method = RequestMethod.POST)
    public JsonResult sendAvatar(HttpServletRequest req) throws IOException, ServletException {
        return userService.uploadAvatar(req);
    }

    /**
     * Updates the user information.
     *
     * @param  user    the JSONObject containing the user information
     *                 (must include the userId)
     * @return         the JsonResult containing the result of the update operation
     */
    @RequestMapping(value = "/update", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
    public JsonResult updateUserInfo(@RequestBody JSONObject user, HttpServletRequest request){
        //此处 user 必须将其的userId 带过来
        Object o = userService.userState(request);
        if(o != (Object) false){
            UserVo userVo =  (UserVo)o;
            String userId = userVo.getUserId();
            user.put("userId", userId);
        }
        return userService.updateUserInfo(user, request);
    }

    @PostMapping("/getUserHistory")
    @ApiOperation("获取用户动态")
    public JsonResult getUserHistory(@RequestBody PageDTO pageDTO, HttpServletRequest request) {
        Object userState = userService.userState(request);
        if (userState.equals(false)) {
            return ResultUtils.error(-1, "用户未登录");
        }
        UserVo user = (UserVo) userState;
        String userId = user.getUserId();
        Pageable pageRequest = PageRequest.of(pageDTO.getPage()-1, pageDTO.getPageSize(), Sort.by(pageDTO.getAsc()? Sort.Direction.ASC: Sort.Direction.DESC,pageDTO.getSortField()));
        return ResultUtils.success(historyDao.findAllByUserId(userId, pageRequest));
    }

    @PostMapping("/handleUserHistory/{hid}")
    @ApiOperation("处理用户动态")
    public JsonResult handleUserHistory(@PathVariable String hid, @RequestBody JSONObject state, HttpServletRequest request) {
        Object userState = userService.userState(request);
        if (userState.equals(false)) {
            return ResultUtils.error(-1, "用户未登录");
        }
        return historyService.UserJoinProject(hid, state.getString("state"));
    }


    @ApiOperation(value = "查询用户拥有的项目")
    @GetMapping("/getProjectAndDataNumByUserId")
    public JsonResult getProjectAndDataNumByUserId(HttpServletRequest request){
        Object userState = userService.userState(request);
        if (userState.equals(false)) {
            return ResultUtils.error(-1, "用户未登录");
        }
        UserVo user = (UserVo) userState;
        String userId = user.getUserId();
        return userService.getProjectAndDataNumByUserId(userId);
    }
}
